#include "EstadoDeTiradaDeDados.h"
#include "EstadoDeDecisionDeResultado.h"
#include "TurnoInvalidoException.h"
#include "TiradaInvalidaException.h"
#include "MensajeDeSolicitudDeTirarDados.h"
#include <list>
using namespace std;

EstadoDeTiradaDeDados::EstadoDeTiradaDeDados(EstadoDeAtaque* estadoDeAtaque)
{
	this->estadoDeAtaque = estadoDeAtaque;
	dadosEnemigoTirados = false;
	dadosAtacanteTirados = false;
}

void EstadoDeTiradaDeDados::tirarDados(Jugador* jugador, unsigned int cantidadDeDados) {
	list<Dado*>* dadosAtacante = this->estadoDeAtaque->getDadosTiradosPorAtacante();
	list<Dado*>* dadosDefensor = this->estadoDeAtaque->getDadosTiradosPorDefensor(); 
	Ataque* ataque = this->estadoDeAtaque->getAtaque();
	JuegoServerImp* juego = this->estadoDeAtaque->getEstadoDeRealizacionDePartida()->getJuego();
	//Si es el atacante:
	if (jugador->equals(ataque->getJugadorAtacante())) {
		dadosAtacante->clear();
		//Valido que tire los dados que indico al momento de declarar el ataque.
		if (cantidadDeDados == ataque->getCantidadDeDadosParaAtacar()) {
			list<Dado*>::iterator it = juego->getDadosAtacante()->begin();
			for (int i = 0; i < cantidadDeDados; i++) {
				juego->getTiradorDeDados()->tirar(*(it));
				dadosAtacante->push_back(*(it));
				it++;
			}
			dadosAtacanteTirados = true;
			if (dadosEnemigoTirados) {
				this->estadoDeAtaque->setEstado(this->estadoDeAtaque->getEstadoDeDecisionDeResultado());
				this->estadoDeAtaque->decidirResultado();
				dadosEnemigoTirados = false;
				dadosAtacanteTirados = false;
			}
			else {
				MensajeDeSolicitudDeTirarDados mensaje(*ataque);
				juego->getServer()->enviarMensaje(juego->getJugador(ataque->getTerritorioEnemigo()->getEnPoderDe()),mensaje);
			}
		}
		else
			throw TiradaInvalidaException();
	}
	//Sino, si es el enemigo, debo ver que este tirando la cantidad de dados adecuada:
	else if (jugador->equals(juego->getJugador(ataque->getTerritorioEnemigo()->getEnPoderDe()))) {
		if ((cantidadDeDados <= 2) && (cantidadDeDados <= ataque->getTerritorioEnemigo()->getCantidadDeEjercitos())) { 
			dadosDefensor->clear();
			list<Dado*>::iterator it = juego->getDadosDefensor()->begin();
			for (int i = 0; i < cantidadDeDados; i++) {
				juego->getTiradorDeDados()->tirar(*(it));
				dadosDefensor->push_back(*(it));
				it++;
			}
			dadosEnemigoTirados = true;
			if (dadosAtacanteTirados){
				this->estadoDeAtaque->setEstado(this->estadoDeAtaque->getEstadoDeDecisionDeResultado());
				this->estadoDeAtaque->decidirResultado();
				dadosEnemigoTirados = false;
				dadosAtacanteTirados = false;
			}
			else{
				MensajeDeSolicitudDeTirarDados mensaje(*ataque);
				juego->getServer()->enviarMensaje(ataque->getJugadorAtacante(),mensaje);
			}
		}
		else 
			throw TiradaInvalidaException();
	}
	else 
		throw TurnoInvalidoException();
}

EstadoDeTiradaDeDados::~EstadoDeTiradaDeDados()
{
}
